using System;
using System.Collections.Generic;
using System.Text;
using System.DirectoryServices;
using Suucha.Adsi;

namespace Suucha.AdHelper
{
    public sealed class GroupHelper
    {
        public static GroupInfo GetGroupInfo(string name, bool getUsers)
        {
            DirectorySearcher ds = AdsiCommon.GetDirectorySearcher(Common.ADPath, Common.UserName, Common.Password);
            ds.Filter = "(&(objectClass=group)(name=" + name + "))";
            GroupInfo info;
            try
            {
                SearchResult result = ds.FindOne();
                info = GetGroupInfoByPath(result.Path, getUsers);
            }
            catch
            {
                info = new GroupInfo();
            }
            return info;
        }
        private static string GetPathByName(string name)
        {
            DirectorySearcher ds = AdsiCommon.GetDirectorySearcher(Common.ADPath, Common.UserName, Common.Password);
            ds.Filter = "(&(objectClass=group)(name=" + name + "))";
            string path = "";
            try
            {
                SearchResult result = ds.FindOne();
                path = result.Path;

            }
            catch
            {
                path = "";
            }
            return path;
        }
        public static GroupInfo GetGroupInfo(Guid groupId, bool getUsers)
        {
            DirectorySearcher ds = AdsiCommon.GetDirectorySearcher(Common.ADPath, Common.UserName, Common.Password);
            ds.Filter = "(&(objectClass=group))";
            GroupInfo info = new GroupInfo();
            try
            {
                SearchResultCollection results = ds.FindAll();
                //info = new GroupInfo();
                foreach (SearchResult result in results)
                {
                    Guid guid = Common.GetGuid(result);
                    if (groupId == guid)
                    {
                        info = GetGroupInfoByPath(result.Path, getUsers);
                        break;
                    }
                }
            }
            catch
            {
            }
            return info;
        }

        internal static GroupInfo GetGroupInfoByPath(string path, bool getUsers)
        {
            GroupInfo info = new GroupInfo();
            DirectoryEntry de = AdsiCommon.GetDirectoryEntry(path, Common.UserName, Common.Password);
            if (de.SchemaClassName != "group")
                return info;
            info.Name = (string)de.Properties["name"].Value;
            info.Id = de.Guid;
            if (getUsers)
            {
                info.Users = GetUsers(de);
                info.UserIds = new List<Guid>();
                for (int i = 0; i < info.Users.Count; i++)
                    info.UserIds.Add(info.Users[i].Id);
            }
            return info;
        }

        internal static void GetMemberOf(string path, List<GroupInfo> groups)
        {
            DirectoryEntry de = AdsiCommon.GetDirectoryEntry(path, Common.UserName, Common.Password);
            if (de.SchemaClassName != "group")
                return;
            PropertyValueCollection memberOf = de.Properties["memberOf"];
            if (memberOf == null)
                return;
            if (memberOf.Count == 0)
                return;
            foreach (string dn in memberOf)
            {
                GroupInfo groupInfo = GetGroupInfoByPath(Common.ADPath + "/" + dn, false);
                if (groupInfo != null)
                    if (groupInfo.Id != Guid.Empty)
                    {
                        groups.Add(groupInfo);
                        GetMemberOf(Common.ADPath + "/" + dn, groups);
                    }
            }
        }

        private static List<UserInfo> GetUsers(DirectoryEntry de)
        {
            List<UserInfo> users = new List<UserInfo>();
            PropertyValueCollection userDn = de.Properties["member"];
            foreach (string dn in userDn)
            {
                UserInfo user = UserHelper.GetUserInfoByPath(Common.ADPath + "/" + dn, false);
                if(user != null)
                    if(user.Id != Guid.Empty)
                        users.Add(user);
            }
            return users;
        }
        private static List<UserInfo> GetUsersOnly(DirectoryEntry de)
        {
            List<UserInfo> users = new List<UserInfo>();
            PropertyValueCollection userDn = de.Properties["member"];
            foreach (string dn in userDn)
            {
                UserInfo user = UserHelper.GetUserInfoOnly(Common.ADPath + "/" + dn);
                if (user != null)
                    if (user.Id != Guid.Empty)
                        users.Add(user);
            }
            return users;

        }
        public static List<UserInfo> GetGroupUser(string groupName)
        {
            string path = GetPathByName(groupName);
            return GetUsersOnly(AdsiCommon.GetDirectoryEntry(path, Common.UserName, Common.Password));
        }
    }
}
